<script lang="ts" setup>
	import config from './config'
	import { cloneDeep } from 'lodash-es'
	import datasetApi from '@/views/plugin/dashboard/api/datasetApi'
	import { designStore } from '@/views/plugin/dashboard/store'
	import { formatWeatherData, getWeatherByCityCode, parseWeatherType } from './weatherApi'
	import { computed, onMounted, reactive, ref, watch } from 'vue'
	import { SyncOutlined } from '@ant-design/icons-vue'

	import weather01 from './image/weather01.png'
	import weather02 from './image/weather02.png'
	import weather03 from './image/weather03.png'
	import weather04 from './image/weather04.png'
	import weather05 from './image/weather05.png'
	import weather06 from './image/weather06.png'
	import weather07 from './image/weather07.png'
	import weather08 from './image/weather08.png'
	import weather09 from './image/weather09.png'
	import weather10 from './image/weather10.png'
	import weather11 from './image/weather11.png'

	const emit = defineEmits(['upDataConfig'])
	const iconList = ref([
		{ source: weather01, key: 'weather01' },
		{ source: weather02, key: 'weather02' },
		{ source: weather03, key: 'weather03' },
		{ source: weather04, key: 'weather04' },
		{ source: weather05, key: 'weather05' },
		{ source: weather06, key: 'weather06' },
		{ source: weather07, key: 'weather07' },
		{ source: weather08, key: 'weather08' },
		{ source: weather09, key: 'weather09' },
		{ source: weather10, key: 'weather10' },
		{ source: weather11, key: 'weather11' }
	])
	const useDesignStore = designStore()
	const props = defineProps({
		config: {
			type: Object,
			default: () => config
		}
	})

	// 创建本地配置缓存，用于存储用户修改但尚未确认的配置
	const localConfig = reactive(cloneDeep(props.config || config))

	// 初始化本地配置
	onMounted(() => {
		Object.assign(config, cloneDeep(localConfig))
		// 加载天气数据
		onReload()
	})

	// 监听props.config的变化，更新本地配置
	watch(
		() => props.config,
		(newConfig) => {
			if (newConfig) {
				Object.assign(localConfig, cloneDeep(newConfig))
			}
		},
		{ deep: true }
	)

	// 更新配置
	const updateConfig = () => {
		emit('upDataConfig', cloneDeep(localConfig))
	}

	// 容器样式
	const container = computed(() => ({
		padding: `${localConfig.style.paddingT}px ${localConfig.style.paddingR}px ${localConfig.style.paddingB}px ${localConfig.style.paddingL}px`,
		background: localConfig.style.bgColor,
		borderColor: localConfig.style.borderColor,
		borderWidth: localConfig.style.borderWidth + 'px',
		borderStyle: localConfig.style.borderStyle,
		borderTopLeftRadius: localConfig.style.bgRTL + 'px',
		borderTopRightRadius: localConfig.style.bgRTR + 'px',
		borderBottomLeftRadius: localConfig.style.bgRBL + 'px',
		borderBottomRightRadius: localConfig.style.bgRBR + 'px',
		boxShadow: `${localConfig.style.shadowX}px ${localConfig.style.shadowY}px ${localConfig.style.shadowDegree}px ${localConfig.style.shadowColor}`
	}))

	const locationStyle = computed(() => ({
		fontSize: localConfig.style.locationSize + 'px',
		color: localConfig.style.locationColor,
		fontWeight: localConfig.style.locationWeight ? 800 : 500,
		fontStyle: localConfig.style.locationStyle ? 'italic' : '',
		textDecoration: localConfig.style.locationLine ? 'underline' : ''
	}))

	const temperatureStyle = computed(() => ({
		fontSize: localConfig.style.temperatureSize + 'px',
		color: localConfig.style.temperatureColor,
		fontWeight: localConfig.style.temperatureWeight ? 800 : 500,
		fontStyle: localConfig.style.temperatureStyle ? 'italic' : '',
		textDecoration: localConfig.style.temperatureLine ? 'underline' : ''
	}))

	const dateStyle = computed(() => ({
		fontSize: localConfig.style.dateSize + 'px',
		color: localConfig.style.dateColor,
		fontWeight: localConfig.style.dateWeight ? 800 : 500,
		fontStyle: localConfig.style.dateStyle ? 'italic' : '',
		textDecoration: localConfig.style.dateLine ? 'underline' : ''
	}))

	const iconStyle = computed(() => ({
		height: localConfig.style.iconSize + 'px',
		width: localConfig.style.iconSize + 'px',
		color: localConfig.style.iconColor
	}))

	// 天气数据相关
	const loading = ref(false)
	const error = ref(null)
	const weatherData = ref(null)

	// 加载天气数据
	const onReload = async () => {
		if (!localConfig.dataParams.cityCode?.value) return

		loading.value = true
		error.value = null

		try {
			const result = await getWeatherByCityCode(localConfig.dataParams.cityCode.value)
			if (result.success) {
				weatherData.value = formatWeatherData(result.data)

				// 更新本地配置中的数据
				if (weatherData.value) {
					localConfig.dataParams.area.value = weatherData.value.cityName
					localConfig.dataParams.temperature.value = weatherData.value.temperature
					localConfig.dataParams.weather.value =
						parseWeatherType(weatherData.value.weatherType) === 'weather01' ? '1' : '2'
					localConfig.dataParams.toDate.value = weatherData.value.date
					localConfig.dataParams.humidity.value = weatherData.value.humidity
					localConfig.dataParams.quality.value = weatherData.value.quality
					localConfig.dataParams.forecast.value = weatherData.value.forecast

					// 更新最后更新时间
					localConfig.weatherConfig.lastUpdated = new Date().toISOString()

					// 更新配置
					updateConfig()
				}
			} else {
				error.value = result.message
			}
		} catch (err) {
			error.value = err.message || '获取天气数据失败'
		} finally {
			loading.value = false
		}
	}

	// 数据源 --- 调接口
	const dataSource = ref({})
	// 接数据源
	const dataSet = reactive(cloneDeep(localConfig.dataParams))

	// 更新数据集
	const updateDataSet = () => {
		if (dataSource.value && Object.keys(dataSource.value).length > 0) {
			dataSet.toDate.value = dataSource.value[localConfig.dataParams.toDate.field] || dataSet.toDate.value
			dataSet.weather.value = dataSource.value[localConfig.dataParams.weather.field] || dataSet.weather.value
			dataSet.temperature.value =
				dataSource.value[localConfig.dataParams.temperature.field] || dataSet.temperature.value
			dataSet.area.value = dataSource.value[localConfig.dataParams.area.field] || dataSet.area.value
			dataSet.cityCode.value = dataSource.value[localConfig.dataParams.cityCode.field] || dataSet.cityCode.value

			// 如果有城市编码，加载天气数据
			if (dataSet.cityCode.value) {
				onReload()
			}
		}
	}

	watch(
		() => localConfig.dataSetConfig.dataSetJson,
		(newVal: any, oldVal: any) => {
			updateDataSet()
		},
		{ deep: true, immediate: true }
	)

	// 组件绑定数据 静态 / 数据源
	const formState = computed(() => {
		return localConfig.dataParams
	})

	// 监听数据源变化
	watch(
		dataSource,
		() => {
			updateDataSet()
		},
		{ deep: true }
	)

	// 暴露方法给父组件
	defineExpose({
		onReload
	})
</script>

<template>
	<div class="container" :style="container">
		<!-- 加载状态 -->
		<a-spin :spinning="loading">
			<!-- 错误提示 -->
			<a-alert v-if="error" type="error" :message="error" class="mb-2" />

			<!-- 天气卡片样式1 -->
			<div v-if="localConfig.style.type === 1" class="h-[100%] flex flex-col justify-around">
				<div class="flex justify-between items-center">
					<span :style="dateStyle">{{ formState.toDate?.value }}</span>
					<span :style="locationStyle">{{ formState.area?.value }}</span>
				</div>
				<div class="w-[100%] flex justify-between items-center">
					<div class="flex flex-col">
						<span :style="temperatureStyle">{{ formState.temperature?.value }}℃</span>
						<div class="text-xs mt-1">
							<span>湿度: {{ formState.humidity?.value }}</span>
							<span class="ml-2">空气质量: {{ formState.quality?.value }}</span>
						</div>
					</div>
					<div v-for="item in localConfig.style.columns" :key="item.key" class="inline-block">
						<img
							:style="iconStyle"
							v-if="item.key === formState.weather?.value"
							:src="iconList.find((d) => d.key === item.icon).source"
						/>
					</div>
				</div>
				<!-- 天气预报 -->
				<div
					v-if="weatherData && weatherData.forecast && weatherData.forecast.length > 0"
					class="forecast-container mt-2"
				>
					<div class="flex justify-between">
						<div
							v-for="(item, index) in weatherData.forecast.slice(0, 3)"
							:key="index"
							class="forecast-item text-center"
						>
							<div class="text-xs">{{ item.week }}</div>
							<img
								:src="iconList.find((d) => d.key === item.weatherIconKey).source"
								class="forecast-icon mx-auto my-1"
								style="width: 20px; height: 20px"
							/>
							<div class="text-xs">{{ item.highTemp }}/{{ item.lowTemp }}</div>
						</div>
					</div>
				</div>
			</div>

			<!-- 天气卡片样式2 -->
			<div v-if="localConfig.style.type === 2" class="h-[100%] flex items-center justify-between">
				<div>
					<div v-for="item in localConfig.style.columns" :key="item.key" class="inline-block">
						<img
							v-if="item.key === formState.weather.value"
							:style="iconStyle"
							:src="iconList.find((d) => d.key === item.icon).source"
						/>
					</div>
				</div>
				<div class="flex flex-col items-end">
					<div :style="temperatureStyle">{{ formState.temperature.value }}℃</div>
					<div :style="locationStyle">{{ formState.area?.value }}</div>
					<div :style="dateStyle">{{ formState.toDate?.value }}</div>
					<div class="text-xs mt-1">
						<span>湿度: {{ formState.humidity?.value }}</span>
						<span class="ml-2">空气质量: {{ formState.quality?.value }}</span>
					</div>
				</div>
			</div>

			<!-- 天气卡片样式3 -->
			<div v-if="localConfig.style.type === 3" class="h-[100%] flex flex-col justify-around">
				<div class="flex justify-between items-center">
					<div :style="locationStyle">{{ formState.area?.value }}</div>
					<div :style="dateStyle">{{ formState.toDate?.value }}</div>
				</div>
				<div class="flex items-center justify-between">
					<div class="flex flex-col">
						<span :style="temperatureStyle">{{ formState.temperature?.value }}℃</span>
						<div class="text-xs mt-1">
							<span>湿度: {{ formState.humidity?.value }}</span>
							<span class="ml-2">空气质量: {{ formState.quality?.value }}</span>
						</div>
					</div>
					<div v-for="item in localConfig.style.columns" :key="item.key" class="inline-block">
						<img
							:style="iconStyle"
							v-if="item.key === formState.weather?.value"
							:src="iconList.find((d) => d.key === item.icon).source"
						/>
					</div>
				</div>
				<!-- 天气预报 -->
				<div
					v-if="weatherData && weatherData.forecast && weatherData.forecast.length > 0"
					class="forecast-container mt-2"
				>
					<div class="flex justify-between">
						<div
							v-for="(item, index) in weatherData.forecast.slice(0, 3)"
							:key="index"
							class="forecast-item text-center"
						>
							<div class="text-xs">{{ item.week }}</div>
							<img
								:src="iconList.find((d) => d.key === item.weatherIconKey).source"
								class="forecast-icon mx-auto my-1"
								style="width: 20px; height: 20px"
							/>
							<div class="text-xs">{{ item.highTemp }}/{{ item.lowTemp }}</div>
						</div>
					</div>
				</div>
			</div>

			<!-- 天气卡片样式4 -->
			<div v-if="localConfig.style.type === 4" class="h-[100%] flex flex-col justify-around">
				<div class="flex items-center justify-between">
					<span :style="temperatureStyle">{{ formState.temperature.value }}℃</span>
					<div v-for="item in localConfig.style.columns" :key="item.key" class="inline-block">
						<img
							:style="iconStyle"
							v-if="item.key === formState.weather.value"
							:src="iconList.find((d) => d.key === item.icon).source"
						/>
					</div>
				</div>
				<div class="flex items-center justify-between">
					<span :style="locationStyle">{{ formState.area?.value }}</span>
					<span :style="dateStyle">{{ formState.toDate?.value }}</span>
				</div>
				<div class="text-xs">
					<span>湿度: {{ formState.humidity?.value }}</span>
					<span class="ml-2">空气质量: {{ formState.quality?.value }}</span>
				</div>
			</div>

			<!-- 刷新按钮 -->
			<div v-if="localConfig.weatherConfig?.showRefreshButton" class="refresh-button mt-2 text-right">
				<a-button type="link" size="small" @click="loadWeatherData" :loading="loading">
					<template #icon><sync-outlined /></template>
					刷新
				</a-button>
			</div>
		</a-spin>
	</div>
</template>

<style lang="less" scoped>
	.container {
		// 修改圆角半径为不同的值
		// border-radius: 10px; // 调整为图片中的圆角弧度
		// 添加阴影效果
		// box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
		padding: 25px; // 增加内边距
		overflow: hidden;
		height: 100%;
		width: 100%;
		// background-color: white;
	}

	.city-selector {
		width: 100%;
	}

	.forecast-container {
		border-top: 1px solid #f0f0f0;
		padding-top: 8px;
	}

	.forecast-item {
		flex: 1;
	}
</style>
